package com.wfit.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wfit.context.UserContext;
import com.wfit.dto.OrderPageDTO;
import com.wfit.dto.OrderStatusDTO;
import com.wfit.dto.PageDTO;
import com.wfit.enumeration.OrderStatusEnum;
import com.wfit.mapper.CartMapper;
import com.wfit.mapper.CommodityMapper;
import com.wfit.mapper.OrderDetailMapper;
import com.wfit.mapper.OrderMapper;
import com.wfit.po.Cart;
import com.wfit.po.Commodity;
import com.wfit.po.Order;
import com.wfit.po.OrderDetail;
import com.wfit.result.Result;
import com.wfit.service.CommodityService;
import com.wfit.service.OrderService;
import com.wfit.utils.OrderUtil;
import com.wfit.dto.OrderDTO;
import com.wfit.vo.OrderSearchVO;
import com.wfit.vo.OrderVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

@Autowired
private CartMapper cartMapper;
@Autowired
private OrderDetailMapper orderDetailMapper;
@Autowired
private CommodityMapper commodityMapper;
    @Override
    public Result search(OrderPageDTO dto) {

        Page<Order> page = dto.toMpPageDefaultSortByCreateTimeDesc();
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();

        // 格式化数据
        ArrayList<LocalDateTime> localDateTimes = new ArrayList<>();
        if (dto.getDateRange() != null && dto.getDateRange().size() == 2) {
            for (Object o : dto.getDateRange()) {
                String jsonString = JSON.toJSONString(o);
                LocalDateTime localDateTime = JSON.parseObject(jsonString, LocalDateTime.class);
                localDateTimes.add(localDateTime);
            }
            // 时间范围查询
            queryWrapper.between(Order::getCreateTime, localDateTimes.get(0), localDateTimes.get(1));
        }

        // 订单号查询
        queryWrapper.like(dto.getOrderNo() != null && dto.getOrderNo() != "",Order::getOrderNo, dto.getOrderNo());
        // 手机号查询
        queryWrapper.like(dto.getPhone() != null && dto.getPhone() != "",Order::getPhone, dto.getPhone());
        // 状态查询
        queryWrapper.eq(dto.getStatus() != null,Order::getStatus, dto.getStatus());
        page = page(page,queryWrapper);
        PageDTO<OrderSearchVO> pageVO = PageDTO.of(page, new Function<Order, OrderSearchVO>() {
            @Override
            public OrderSearchVO apply(Order order) {
                OrderSearchVO orderSearchVO = new OrderSearchVO();
                for (OrderStatusEnum orderStatusEnum : OrderStatusEnum.values()) {
                    if(orderStatusEnum.getStatus().equals(order.getStatus())){
                        orderSearchVO.setStatusName(orderStatusEnum.getStatusName());
                    }
                }
                BeanUtils.copyProperties(order, orderSearchVO);
                List<OrderDetail> orderDetails = orderDetailMapper.selectList(Wrappers.lambdaQuery(OrderDetail.class).eq(OrderDetail::getOrderId, order.getId()));
                orderSearchVO.setOrderList(orderDetails);
                if (orderSearchVO.getReceiver() == null) {
                    orderSearchVO.setReceiver("无");
                }
                return orderSearchVO;
            }
        });
        return Result.success(pageVO);
    }
//    private final Short STATUS_DISPATCHING = 2;
//    private final Short STATUS_COMPLETED = 3;
//    private final Short CANCELLED_COMPLETED = 3;
    @Override
    public Result orderStatus(OrderStatusDTO dto) {
        if (dto.getStatus().equals(OrderStatusEnum.CANCELED.getStatus())) {
            lambdaUpdate().eq(Order::getId, dto.getId()).set(Order::getStatus, dto.getStatus());
            return Result.success("正在配送中");
        }
        if (dto.getStatus().equals(OrderStatusEnum.COMPLETED.getStatus())) {
            lambdaUpdate().eq(Order::getId, dto.getId()).set(Order::getStatus, dto.getStatus());
            return Result.success("已取消");
        }
        if (dto.getStatus().equals(OrderStatusEnum.REFUNDED.getStatus())) {
            lambdaUpdate().eq(Order::getId, dto.getId()).set(Order::getStatus, dto.getStatus());
            return Result.success("已完成");
        }

        return Result.error("状态跟新失败");
    }

    @Override
    public Result generatorOrder(OrderDTO dto) {
        Integer count = 0;
        Double price = 0.0;
        Order order = new Order();
        OrderVO orderVO = new OrderVO();
        ArrayList<OrderDetail> orderDetails = new ArrayList<>();
        if (dto.getMode().equalsIgnoreCase("cart") ) {
            String[] cartIds = dto.getCartIds().split(",");
            for (String cartId : cartIds) {
                Cart cart = cartMapper.selectById(cartId);
                count += cart.getNumber();
                price += cart.getAmount() * cart.getNumber();
            }
            saveOrder( order, count, price);
            BeanUtils.copyProperties(order, orderVO);
            for (String cartId : cartIds) {
                saveOrderDetail(cartId, order.getId(), orderDetails);
            }

        } else if (dto.getMode().equalsIgnoreCase("buyNow") ){
            Commodity commodity = commodityMapper.selectById(dto.getCartId());
            count += dto.getNumber();
            price += dto.getNumber() * commodity.getPrice();
            saveOrder(order, count, price);

            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(order.getId());
            orderDetail.setNumber(count);
            orderDetail.setAmount(price);
            orderDetail.setName(commodity.getName());
            orderDetail.setImage(commodity.getImage());
            orderDetail.setCId(commodity.getId());
            orderDetailMapper.insert(orderDetail);
            orderDetails.add(orderDetail);

            commodity.setNumber(commodity.getNumber() - dto.getNumber());
            commodityMapper.updateById(commodity);
        }
        BeanUtils.copyProperties(order, orderVO);
        orderVO.setOrderList(orderDetails);
        return Result.success(orderVO);
    }

    @Override
    public Result getUserList(String dto) {
        LambdaQueryChainWrapper<Order> lambdaQueryChainWrapper = lambdaQuery().eq(Order::getCreator, UserContext.getUser());
        List<Order> list = null;
        if (dto.equalsIgnoreCase("all")) {
             list = lambdaQueryChainWrapper.list();
        }
        if (dto.equalsIgnoreCase("payment")) {
            list = lambdaQueryChainWrapper.eq(Order::getStatus, OrderStatusEnum.PAYMENT.getStatus()).list();
        }
        if (dto.equalsIgnoreCase("delivery")) {
            list = lambdaQueryChainWrapper.eq(Order::getStatus, OrderStatusEnum.PENDING.getStatus()).list();
        }
        if (dto.equalsIgnoreCase("received")) {
            list = lambdaQueryChainWrapper.eq(Order::getStatus, OrderStatusEnum.CANCELED.getStatus()).list();
        }
        if (dto.equalsIgnoreCase("completed")) {
            list = lambdaQueryChainWrapper.eq(Order::getStatus, OrderStatusEnum.REFUNDED.getStatus()).list();
        }
        List<OrderVO> orderVOS = BeanUtil.copyToList(list, OrderVO.class);
        for (OrderVO order : orderVOS) {
            Integer id = order.getId();
            List<OrderDetail> orderDetails = orderDetailMapper.selectList(Wrappers.<OrderDetail>lambdaQuery().eq(OrderDetail::getOrderId, id));

            order.setOrderList(orderDetails);
        }
        return Result.success(orderVOS);
    }

    @Override
    public Result getOrderOne(String orderId) {
        Order order = getById(orderId);
        if (order == null) {
            return Result.error("订单不存在或已经过期");
        }
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(Wrappers.<OrderDetail>lambdaQuery().eq(OrderDetail::getOrderId, orderId));
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(order, orderVO);
        orderVO.setOrderList(orderDetails);
        return Result.success(orderVO);
    }

    @Override
    public Result updateOrderStatus(String status , String orderId) {
        Order order = getById(orderId);
        order.setBeforeStatus(order.getStatus());
        order.setStatus(Integer.valueOf(status));
        updateById(order);
        return Result.success();
    }

    @Override
    public Result cancelOrder(String orderId) {
        Order order = getById(orderId);
        if (order.getStatus().equals(OrderStatusEnum.APPLYCOMPLETED.getStatus())) {
            order.setStatus(order.getBeforeStatus());
        }
        updateById(order);
        return Result.success();
    }

    private void saveOrderDetail(String cartId, Integer oid, ArrayList<OrderDetail> orderDetails) {
        Cart cart = cartMapper.selectById(cartId);
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(oid);
        orderDetail.setNumber(cart.getNumber());
        orderDetail.setAmount(cart.getAmount());
        orderDetail.setName(cart.getName());
        orderDetail.setImage(cart.getImage());
        orderDetail.setCId(cart.getCid());
        orderDetailMapper.insert(orderDetail);
        orderDetails.add(orderDetail);
        cartMapper.deleteById(cartId);
    }

    private void saveOrder( Order order, Integer count, Double price) {
        //        order.setReceiver(dto.getReceiver());
//        order.setAddress(dto.getAddress());
//        order.setPhone(dto.getPhone());
        order.setCreateTime(LocalDateTime.now());
        order.setCreator(UserContext.getUser().toString());
        order.setStatus(OrderStatusEnum.PAYMENT.getStatus());
        order.setAllCount(count);
        order.setAllPrice(price);
//        order.setTruePrice(truePrice);
//        order.setDiscount(dto.getDiscount());
//        order.setDiscount(dto.getDelivery());
        String string = OrderUtil.idGenerator();
        order.setOrderNo(string);
        order.setTruePrice(price);
        save(order);
    }
}
